<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace User\Service\Common\AppLogin;

use Admin\Data\Common;
use Laminas\Json\Json;
use Laminas\Session\Container;

class QqLogin
{
    const GET_AUTH_CODE_URL     = "https://graph.qq.com/oauth2.0/authorize";
    const GET_ACCESS_TOKEN_URL  = "https://graph.qq.com/oauth2.0/token";
    const GET_OPENID_URL        = "https://graph.qq.com/oauth2.0/me";
    const GET_USER_INFO_URL     = "https://graph.qq.com/user/get_user_info";

    public $redirectUri;

    private $customerConfig = [];
    private $loginSession;

    public function __construct()
    {
        $this->customerConfig   = Common::readConfigFile('customer');
        $this->loginSession     = new Container('qqSession');
    }

    public function toLogin()
    {
        $loginKey = [
            'response_type' => 'code',
            'client_id'     => $this->customerConfig['qq_app_id'],
            'redirect_uri'  => $this->redirectUri,
            'state'         => md5(uniqid(rand(), TRUE)),
            'scope'         => 'get_user_info,add_share,list_album,add_album,upload_pic,add_topic,add_one_blog,add_weibo,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idolist,add_idol,del_idol,get_tenpay_addr'
        ];

        $this->loginSession->offsetSet('qqState', $loginKey['state']);

        header("Location: {$this->combineUrl(self::GET_AUTH_CODE_URL, $loginKey)}");
        exit();
    }

    /**
     * 跳转返回处理
     */
    public function loginCallBack()
    {
        if ($this->loginSession->offsetGet('qqState') != $_GET['state']) {
            exit('<h2>The state does not match. You may be a victim of CSRF.</h2>');
        }

        $loginKey = [
            'grant_type'    => 'authorization_code',
            'client_id'     => $this->customerConfig['qq_app_id'],
            'redirect_uri'  => $this->redirectUri,
            'client_secret' => $this->customerConfig['qq_app_key'],
            'code'          => $_GET['code']
        ];

        $response = Common::httpGet($this->combineUrl(self::GET_ACCESS_TOKEN_URL, $loginKey));
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response  = substr($response, $lpos + 1, $rpos - $lpos -1);
            $msg = json_decode($response);

            if(isset($msg->error)){
                exit('error:' . $msg->error . 'error:' . $msg->error_description);
            }
        }

        $params = [];
        parse_str($response, $params);

        $this->loginSession->offsetSet('qqAccessToken', $params['access_token']);
    }

    /**
     * openId
     * @return mixed|null
     */
    public function openId()
    {
        $openKey    = ['access_token' => $this->loginSession->offsetGet('qqAccessToken')];
        $response   = Common::httpGet($this->combineUrl(self::GET_OPENID_URL, $openKey));

        //--------检测错误是否发生
        if(strpos($response, "callback") !== false){

            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }

        $user = json_decode($response);
        if(isset($user->error)){
            exit('error:' . $user->error . 'error:' . $user->error_description);
        }

        $this->loginSession->offsetSet('qqOpenId', $user->openid);

        return $user->openid;
    }

    /**
     * unionId
     * @return mixed|null
     */
    public function unionId()
    {
        return '';
    }

    /**
     * 账户信息
     * @return mixed
     */
    public function loginUserInfo()
    {
        $infoKey = [
            'oauth_consumer_key' => $this->customerConfig['qq_app_id'],
            'access_token'       => $this->loginSession->offsetGet('qqAccessToken'),
            'openid'             => $this->loginSession->offsetGet('qqOpenId'),
            'format'             => 'json'
        ];

        $responseArray = Json::decode(Common::httpGet($this->combineUrl(self::GET_USER_INFO_URL, $infoKey)), Json::TYPE_ARRAY);

        //检查返回ret判断api是否成功调用
        if($responseArray['ret'] == 0){
            return $responseArray;
        }else{
            exit('error:' . $responseArray['ret'] . 'error:' . $responseArray['msg']);
        }
    }

    /**
     * 清除使用过的session
     */
    public function clearOtherLoginSession()
    {
        $this->loginSession->getManager()->getStorage()->clear($this->loginSession->getName());
    }

    /**
     * 拼接Url
     * @param $baseUrl
     * @param $keyArray
     * @return string
     */
    private function combineUrl($baseUrl, $keyArray)
    {
        return $baseUrl . '?' . Common::toUrlParams($keyArray);
    }
}